<template>
  <div class="login-container">
    <div class="login-box">
      <div class="login-header">
        <h2>小窝物业管理系统</h2>
        <p>欢迎登录</p>
      </div>

      <div class="login-tabs">
        <el-tabs v-model="activeTab" @tab-click="handleTabClick">
          <el-tab-pane label="账号登录" name="password">
            <el-form
                ref="passwordFormRef"
                :model="passwordForm"
                :rules="passwordRules"
                class="login-form"
            >
              <el-form-item prop="username">
                <el-input
                    v-model="passwordForm.username"
                    placeholder="请输入用户名"
                    prefix-icon="User"
                    size="large"
                />
              </el-form-item>

              <el-form-item prop="password">
                <el-input
                    v-model="passwordForm.password"
                    type="password"
                    placeholder="请输入密码"
                    prefix-icon="Lock"
                    size="large"
                    show-password
                />
              </el-form-item>

              <el-form-item>
                <el-button
                    type="primary"
                    size="large"
                    class="login-btn"
                    :loading="passwordLoading"
                    @click="handlePasswordLogin"
                >
                  登录
                </el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>

          <el-tab-pane label="验证码登录" name="code">
            <el-form
                ref="codeFormRef"
                :model="codeForm"
                :rules="codeRules"
                class="login-form"
            >
              <el-form-item prop="phone">
                <el-input
                    v-model="codeForm.phone"
                    placeholder="请输入手机号"
                    prefix-icon="Phone"
                    size="large"
                />
              </el-form-item>

              <el-form-item prop="code">
                <div class="code-input-group">
                  <el-input
                      v-model="codeForm.code"
                      placeholder="请输入验证码"
                      prefix-icon="Key"
                      size="large"
                      maxlength="4"
                  />
                  <el-button
                      type="primary"
                      :disabled="codeCountdown > 0"
                      @click="handleSendCode"
                  >
                    {{ codeCountdown > 0 ? `${codeCountdown}s` : '获取验证码' }}
                  </el-button>
                </div>
              </el-form-item>

              <el-form-item>
                <el-button
                    type="primary"
                    size="large"
                    class="login-btn"
                    :loading="codeLoading"
                    @click="handleCodeLogin"
                >
                  登录
                </el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>

          <!-- 人脸识别登录标签页 -->
          <el-tab-pane label="人脸识别登录" name="face">
            <div class="face-login-container">
              <!-- 摄像头预览区域 -->
              <div class="face-camera-preview">
                <div class="face-camera-frame">
                  <video ref="videoRef" autoplay playsinline width="320" height="240" />
                  <div v-if="!cameraOpened" class="face-camera-placeholder">
                    <el-icon class="is-loading"><Loading /></el-icon>
                    <span>正在开启摄像头...</span>
                  </div>
                  <div v-if="faceScanning" class="face-scanning-overlay">
                    <div class="scanning-line"></div>
                  </div>
                </div>
              </div>

              <!-- 状态显示 -->
              <div class="face-status">
                <div class="status-indicator" :class="{ 'active': cameraOpened }">
                  <el-icon v-if="cameraOpened" class="is-loading"><Loading /></el-icon>
                  <span>{{ faceStatusMessage }}</span>
                </div>
              </div>

              <!-- 提示信息 -->
              <div class="face-login-info">
                <p>摄像头开启后将自动进行人脸识别</p>
                <p v-if="faceLoading">正在识别中，请保持面部在摄像头范围内...</p>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onUnmounted, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { User, Lock, Phone, Key, Loading } from '@element-plus/icons-vue'
import { loginByPassword, sendVerificationCode, loginByVerificationCode } from '../api/auth.js'
import { captureImageFromVideo } from '../api/opencv.js'
import { uploadImg } from '../api/owner.js'
import { faceLogin } from '../api/login.js'

const router = useRouter()

// 当前激活的标签页
const activeTab = ref('password')

// 表单引用
const passwordFormRef = ref()
const codeFormRef = ref()
const videoRef = ref(null)

// 加载状态
const passwordLoading = ref(false)
const codeLoading = ref(false)
const faceLoading = ref(false)

// 验证码倒计时
const codeCountdown = ref(0)
let countdownTimer = null

// 人脸识别相关状态
const cameraOpened = ref(false)
const faceScanning = ref(false)
const faceStatusMessage = ref('等待开启摄像头')
let faceStreamTracks = []
let faceScanTimer = null // 人脸扫描定时器
const scanInterval = 3000 // 扫描间隔，3秒

// 账号密码登录表单
const passwordForm = reactive({
  username: '',
  password: ''
})

// 验证码登录表单
const codeForm = reactive({
  phone: '',
  code: ''
})

// 账号密码登录验证规则
const passwordRules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, message: '密码长度不能少于6位', trigger: 'blur' }
  ]
}

// 验证码登录验证规则
const codeRules = {
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
  ],
  code: [
    { required: true, message: '请输入验证码', trigger: 'blur' },
    { pattern: /^\d{4}$/, message: '验证码为4位数字', trigger: 'blur' }
  ]
}

// 标签页切换
const handleTabClick = (tab) => {
  // 清空表单
  passwordForm.username = ''
  passwordForm.password = ''
  codeForm.phone = ''
  codeForm.code = ''

  // 清除验证
  passwordFormRef.value?.clearValidate()
  codeFormRef.value?.clearValidate()

  // 如果切换到人脸识别标签页，开启摄像头
  if (tab.props.name === 'face') {
    openCamera()
  } else {
    // 如果切换到其他标签页，关闭摄像头
    closeCamera()
  }
}

// 账号密码登录
const handlePasswordLogin = async () => {
  try {
    await passwordFormRef.value.validate()
    passwordLoading.value = true

    const response = await loginByPassword(passwordForm)
    console.log('登录响应:', response.data)

    if (response.data.code === 0) {
      // 从msg字段获取token，因为后端可能将token放在了msg字段
      const token = response.data.data || response.data.msg
      console.log('登录成功，token数据:', token)
      console.log('token类型:', typeof token)
      console.log('token是否为null:', token === null)
      console.log('token是否为空字符串:', token === '')

      // 保存token
      sessionStorage.setItem('token', token)
      console.log('保存到sessionStorage的token:', sessionStorage.getItem('token'))

      ElMessage.success('登录成功')

      // 跳转到首页
      router.push('/')
    } else {
      ElMessage.error(response.data.msg || '登录失败')
    }
  } catch (error) {
    console.error('登录失败:', error)
    console.log('错误详情:', error.response?.data)
    ElMessage.error('登录失败，请检查用户名和密码')
  } finally {
    passwordLoading.value = false
  }
}

// 发送验证码
const handleSendCode = async () => {
  try {
    // 验证手机号
    await codeFormRef.value.validateField('phone')

    const response = await sendVerificationCode({ phone: codeForm.phone })
    console.log('发送验证码响应:', response.data)

    if (response.data.code === 0) {
      ElMessage.success('验证码发送成功')
      startCountdown()
    } else {
      ElMessage.error(response.data.msg || '验证码发送失败')
    }
  } catch (error) {
    console.error('发送验证码失败:', error)
    console.log('错误详情:', error.response?.data)
    ElMessage.error('验证码发送失败')
  }
}

// 验证码登录
const handleCodeLogin = async () => {
  try {
    await codeFormRef.value.validate()
    codeLoading.value = true

    const response = await loginByVerificationCode(codeForm)
    console.log('验证码登录响应:', response.data)

    if (response.data.code === 0) {
      // 从msg字段获取token，因为后端可能将token放在了msg字段
      const token = response.data.data || response.data.msg
      console.log('验证码登录成功，token数据:', token)
      console.log('token类型:', typeof token)
      console.log('token是否为null:', token === null)
      console.log('token是否为空字符串:', token === '')

      // 保存token
      sessionStorage.setItem('token', token)
      console.log('保存到sessionStorage的token:', sessionStorage.getItem('token'))

      ElMessage.success('登录成功')

      // 跳转到首页
      router.push('/')
    } else {
      ElMessage.error(response.data.msg || '登录失败')
    }
  } catch (error) {
    console.error('登录失败:', error)
    console.log('错误详情:', error.response?.data)
    ElMessage.error('登录失败，请检查验证码')
  } finally {
    codeLoading.value = false
  }
}

// 开始倒计时
const startCountdown = () => {
  codeCountdown.value = 60
  countdownTimer = setInterval(() => {
    codeCountdown.value--
    if (codeCountdown.value <= 0) {
      clearInterval(countdownTimer)
    }
  }, 1000)
}

// 打开摄像头
const openCamera = async () => {
  if (cameraOpened.value) return

  if (!videoRef.value) {
    console.error('视频元素未初始化')
    faceStatusMessage.value = '摄像头初始化失败，请刷新页面'
    return
  }

  try {
    faceStatusMessage.value = '正在开启摄像头...'

    const stream = await navigator.mediaDevices.getUserMedia({
      video: {
        width: {ideal: 640},
        height: {ideal: 480},
        facingMode: 'user' // 使用前置摄像头
      }
    })

    videoRef.value.srcObject = stream
    faceStreamTracks = stream.getTracks()

    videoRef.value.onloadedmetadata = () => {
      videoRef.value.play()
          .then(() => {
            cameraOpened.value = true
            faceStatusMessage.value = '摄像头已开启，正在准备人脸识别...'
            // 延迟1秒后开始人脸扫描，给用户一些准备时间
            setTimeout(() => {
              startFaceScan()
            }, 1000)
          })
          .catch(err => {
            console.error('视频播放失败:', err)
            faceStatusMessage.value = '视频播放失败，请刷新页面'
          })
    }
  } catch (err) {
    console.error('摄像头访问失败:', err)
    faceStatusMessage.value = '无法访问摄像头，请确保已授予权限'
  }
}

// 开始人脸扫描
const startFaceScan = () => {
  // 清除可能存在的旧定时器
  if (faceScanTimer) {
    clearInterval(faceScanTimer)
  }

  // 立即执行一次人脸识别
  handleFaceLogin()

  // 设置定时器，定期执行人脸识别
  faceScanTimer = setInterval(() => {
    // 如果当前正在进行识别，则跳过本次扫描
    if (!faceLoading.value) {
      handleFaceLogin()
    }
  }, scanInterval)

  faceStatusMessage.value = '正在自动扫描人脸...'
}

// 停止人脸扫描
const stopFaceScan = () => {
  if (faceScanTimer) {
    clearInterval(faceScanTimer)
    faceScanTimer = null
  }
}

// 关闭摄像头
const closeCamera = () => {
  // 停止人脸扫描
  stopFaceScan()

  if (faceStreamTracks.length > 0) {
    faceStreamTracks.forEach(track => track.stop())
    faceStreamTracks = []
  }

  if (videoRef.value && videoRef.value.srcObject) {
    videoRef.value.srcObject = null
  }

  cameraOpened.value = false
  faceStatusMessage.value = '等待开启摄像头'
}

// 将Base64图像转换为Blob
const base64ToBlob = (base64, mimeType = 'image/jpeg') => {
  // 移除Base64前缀（如果有）
  const base64Data = base64.replace(/^data:image\/(png|jpeg|jpg);base64,/, '')

  // 将Base64转换为二进制
  const byteCharacters = atob(base64Data)
  const byteArrays = []

  for (let i = 0; i < byteCharacters.length; i += 512) {
    const slice = byteCharacters.slice(i, i + 512)

    const byteNumbers = new Array(slice.length)
    for (let j = 0; j < slice.length; j++) {
      byteNumbers[j] = slice.charCodeAt(j)
    }

    const byteArray = new Uint8Array(byteNumbers)
    byteArrays.push(byteArray)
  }

  return new Blob(byteArrays, {type: mimeType})
}

// 人脸识别登录
const handleFaceLogin = async () => {
  if (!cameraOpened.value || !videoRef.value) {
    faceStatusMessage.value = '摄像头未开启，无法进行人脸识别'
    return
  }

  try {
    faceLoading.value = true
    faceScanning.value = true
    faceStatusMessage.value = '正在扫描人脸...'

    // 捕获图像
    const base64Image = captureImageFromVideo(videoRef.value)

    // 将Base64图像转换为Blob
    const imageBlob = base64ToBlob(base64Image)

    // 上传图像到MinIO
    faceStatusMessage.value = '正在上传图像...'
    const uploadResponse = await uploadImg(imageBlob)
    console.log('图像上传响应:', uploadResponse)
    console.log('上传响应详情:', JSON.stringify(uploadResponse.data))

    // 检查响应结构
    if (uploadResponse.data) {
      console.log('响应code:', uploadResponse.data.code)
      console.log('响应data:', uploadResponse.data.data)
      console.log('响应msg:', uploadResponse.data.msg)
    }

    // 修改判断条件，兼容不同的响应结构
    if (uploadResponse.data &&
        (uploadResponse.data.code === 0 || uploadResponse.data.code === 200) &&
        uploadResponse.data.data) {
      // 获取上传后的图像URL
      const imageUrl = uploadResponse.data.data
      console.log('获取到图片URL:', imageUrl)

      // 发送人脸识别登录请求
      faceStatusMessage.value = '正在验证身份...'
      console.log('正在进行人脸识别登录...', imageUrl)

      try {
        console.log('调用faceLogin方法，参数:', imageUrl)
        const loginResponse = await faceLogin(imageUrl)
        console.log('人脸登录响应:', loginResponse)

        if (!loginResponse) {
          throw new Error('未收到登录响应');
        }

        if (loginResponse.data && (loginResponse.data.code === 0 || loginResponse.data.code === 200)) {
          // 人脸识别成功
          faceStatusMessage.value = '识别成功!'
          ElMessage.success('人脸识别成功')

          // 停止扫描
          stopFaceScan()

          // 获取token
          const token = loginResponse.data.data || loginResponse.data.msg
          if (token) {
            // 保存token
            sessionStorage.setItem('token', token)
            console.log('保存到sessionStorage的token:', sessionStorage.getItem('token'))

            // 跳转到首页
            router.push('/')
          } else {
            ElMessage.warning('未获取到有效的登录凭证')
            faceStatusMessage.value = '未获取到有效的登录凭证，继续扫描...'
          }
        } else {
          // 人脸识别失败
          const errorMsg = loginResponse.data?.msg || '人脸识别失败'
          ElMessage.error(errorMsg)
          faceStatusMessage.value = '识别失败，继续扫描...'
          console.log('人脸识别失败:', errorMsg)
        }
      } catch (error) {
        console.error('人脸登录过程中出错:', error)
        ElMessage.error('人脸登录失败: ' + (error.message || '未知错误'))
        faceStatusMessage.value = '登录失败，继续扫描...'
      }
    } else {
      // 图像上传失败或响应结构不符合预期
      console.log('上传响应不符合预期，尝试直接使用响应数据')

      // 尝试从不同的响应结构中获取URL
      let imageUrl = null

      if (uploadResponse.data) {
        if (typeof uploadResponse.data === 'string') {
          // 如果响应直接是字符串URL
          imageUrl = uploadResponse.data
          console.log('从字符串响应获取URL:', imageUrl)
        } else if (uploadResponse.data.data && typeof uploadResponse.data.data === 'string') {
          // 如果URL在data字段中
          imageUrl = uploadResponse.data.data
          console.log('从data字段获取URL:', imageUrl)
        } else if (uploadResponse.data.url) {
          // 如果URL在url字段中
          imageUrl = uploadResponse.data.url
          console.log('从url字段获取URL:', imageUrl)
        } else if (uploadResponse.data.msg && typeof uploadResponse.data.msg === 'string' && uploadResponse.data.msg.includes('http')) {
          // 如果URL在msg字段中
          imageUrl = uploadResponse.data.msg
          console.log('从msg字段获取URL:', imageUrl)
        }
      }

      if (imageUrl) {
        // 如果成功获取到URL，继续人脸识别流程
        console.log('成功从替代方式获取图片URL:', imageUrl)
        faceStatusMessage.value = '正在验证身份...'

        try {
          console.log('调用faceLogin方法，参数:', imageUrl)
          const loginResponse = await faceLogin(imageUrl)
          console.log('人脸登录响应:', loginResponse)

          // 处理登录响应...
          if (loginResponse.data && (loginResponse.data.code === 0 || loginResponse.data.code === 200)) {
            // 人脸识别成功
            faceStatusMessage.value = '识别成功!'
            ElMessage.success('人脸识别成功')

            // 停止扫描
            stopFaceScan()

            // 获取token
            const token = loginResponse.data.data || loginResponse.data.msg
            if (token) {
              // 保存token
              sessionStorage.setItem('token', token)
              console.log('保存到sessionStorage的token:', sessionStorage.getItem('token'))

              // 跳转到首页
              router.push('/')
            } else {
              ElMessage.warning('未获取到有效的登录凭证')
              faceStatusMessage.value = '未获取到有效的登录凭证，继续扫描...'
            }
          } else {
            // 人脸识别失败
            const errorMsg = loginResponse.data?.msg || '人脸识别失败'
            ElMessage.error(errorMsg)
            faceStatusMessage.value = '识别失败，继续扫描...'
            console.log('人脸识别失败:', errorMsg)
          }
        } catch (loginError) {
          console.error('人脸登录过程中出错:', loginError)
          faceStatusMessage.value = '登录失败，继续扫描...'
        }
      } else {
        // 确实无法获取URL
        const errorMsg = uploadResponse.data?.msg || '图片上传失败'
        ElMessage.error(errorMsg)
        faceStatusMessage.value = '图像上传失败，继续扫描...'
        console.log('图像上传失败:', errorMsg)
      }
    }
  } catch (error) {
    console.error('人脸识别登录失败:', error)
    faceStatusMessage.value = '登录失败，继续扫描...'
  } finally {
    faceLoading.value = false
    faceScanning.value = false
  }
}

// 组件挂载时
onMounted(() => {
  // 如果初始标签页是人脸识别，则自动开启摄像头
  if (activeTab.value === 'face') {
    openCamera()
  }
})

// 组件卸载时清除资源
onUnmounted(() => {
  // 清除验证码倒计时
  if (countdownTimer) {
    clearInterval(countdownTimer)
  }

  // 停止人脸扫描
  stopFaceScan()

  // 关闭摄像头
  closeCamera()
})
</script>

<style scoped>
.login-container {
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.login-box {
  background: white;
  border-radius: 12px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
  padding: 40px;
  width: 100%;
  max-width: 400px;
}

.login-header {
  text-align: center;
  margin-bottom: 30px;
}

.login-header h2 {
  color: #333;
  margin-bottom: 8px;
  font-size: 24px;
  font-weight: 600;
}

.login-header p {
  color: #666;
  font-size: 14px;
  margin: 0;
}

.login-tabs {
  margin-top: 20px;
}

.login-form {
  margin-top: 20px;
}

.login-btn {
  width: 100%;
  height: 44px;
  font-size: 16px;
  font-weight: 500;
}

.code-input-group {
  display: flex;
  gap: 12px;
}

.code-input-group .el-input {
  flex: 1;
}

.code-input-group .el-button {
  width: 120px;
  height: 40px;
}

:deep(.el-tabs__nav-wrap::after) {
  display: none;
}

:deep(.el-tabs__item) {
  font-size: 16px;
  font-weight: 500;
}

:deep(.el-tabs__item.is-active) {
  color: #409eff;
}

:deep(.el-input__wrapper) {
  height: 44px;
}

:deep(.el-form-item) {
  margin-bottom: 20px;
}

/* 人脸识别登录样式 */
.face-login-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px 0;
}

.face-camera-preview {
  width: 100%;
  display: flex;
  justify-content: center;
  margin-bottom: 15px;
}

.face-camera-frame {
  position: relative;
  width: 320px;
  height: 240px;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(60, 120, 240, 0.15), 0 1.5px 8px rgba(0, 0, 0, 0.08);
  border: 2px solid #3a5ad7;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.face-camera-frame video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 10px;
}

.face-camera-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  gap: 10px;
}

.face-scanning-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.scanning-line {
  position: absolute;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, transparent, #3a5ad7, transparent);
  animation: scanning 2s linear infinite;
}

@keyframes scanning {
  0% {
    top: 0;
  }
  50% {
    top: 100%;
  }
  100% {
    top: 0;
  }
}

.face-status {
  margin: 15px 0;
  width: 100%;
  display: flex;
  justify-content: center;
}

.status-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: 20px;
  background: #f0f5ff;
  color: #7a8599;
  font-size: 0.9rem;
  transition: all 0.3s;
}

.status-indicator.active {
  background: #e6f7ff;
  color: #1890ff;
}

.face-login-info {
  margin-top: 15px;
  text-align: center;
  width: 100%;
  padding: 10px;
  border-radius: 8px;
  background-color: #f0f5ff;
}

.face-login-info p {
  margin: 5px 0;
  color: #3a5ad7;
  font-size: 14px;
}

.face-login-info p:last-child {
  color: #ff7d00;
  font-weight: 500;
}
</style>